#ifndef WXSPOSITIONSIZEPROPERTY_H
#define WXSPOSITIONSIZEPROPERTY_H

#include "../../properties/wxsproperties.h"
#include "../wxscodercontext.h"


struct wxsPositionSizeData {
  bool IsDefault;
  long X;
  long Y;
  bool DialogUnits;

  inline wxsPositionSizeData(): IsDefault( true ), X( 0 ), Y( 0 ), DialogUnits( false ) {}


  inline wxPoint GetPosition( wxWindow* Parent ) {
    return IsDefault ?
           wxDefaultPosition :
           DialogUnits ? wxDLG_UNIT( Parent, wxPoint( X, Y ) ) : wxPoint( X, Y );
  }


  inline void SetPosition( const wxPoint& Point, wxWindow* Parent ) {
    if( Point == wxDefaultPosition ) {
      IsDefault = true;
    } else {
      IsDefault = false;
      if( DialogUnits ) {
        wxPoint Temp = Parent->ConvertPixelsToDialog( Point );
        X = Temp.x;
        Y = Temp.y;
      } else {
        X = Point.x;
        Y = Point.y;
      }
    }
  }


  wxString GetPositionCode( wxsCoderContext* Context );


  inline wxSize GetSize( wxWindow* Parent ) {
    return IsDefault ?
           wxDefaultSize :
           DialogUnits ? wxDLG_UNIT( Parent, wxSize( X, Y ) ) : wxSize( X, Y );
  }


  inline void SetSize( const wxSize& Size, wxWindow* Parent ) {
    if( Size == wxDefaultSize ) {
      IsDefault = true;
    } else {
      IsDefault = false;
      if( DialogUnits ) {
        wxSize Temp = Parent->ConvertPixelsToDialog( Size );
        X = Temp.GetWidth();
        Y = Temp.GetHeight();
      } else {
        X = Size.GetWidth();
        Y = Size.GetHeight();
      }
    }
  }


  wxString GetSizeCode( wxsCoderContext* Context );

};

typedef wxsPositionSizeData wxsPositionData;
typedef wxsPositionSizeData wxsSizeData;


class wxsPositionSizeProperty: public wxsProperty {
  public:


    wxsPositionSizeProperty(
      const wxString& PGUseDefName,
      const wxString& PGXName,
      const wxString& PGYName,
      const wxString& PGDUName,
      const wxString& DataName,
      long Offset,
      int Priority = 100 );


    virtual const wxString GetTypeName() { return _T( "wxPosition wxSize" ); }

  protected:

    virtual void PGCreate( wxsPropertyContainer* Object, wxPropertyGridManager* Grid, wxPGId Parent );
    virtual bool PGRead( wxsPropertyContainer* Object, wxPropertyGridManager* Grid, wxPGId Id, long Index );
    virtual bool PGWrite( wxsPropertyContainer* Object, wxPropertyGridManager* Grid, wxPGId Id, long Index );
    virtual bool XmlRead( wxsPropertyContainer* Object, TiXmlElement* Element );
    virtual bool XmlWrite( wxsPropertyContainer* Object, TiXmlElement* Element );
    virtual bool PropStreamRead( wxsPropertyContainer* Object, wxsPropertyStream* Stream );
    virtual bool PropStreamWrite( wxsPropertyContainer* Object, wxsPropertyStream* Stream );

  private:
    wxString PGXName;
    wxString PGYName;
    wxString PGDUName;
    wxString DataName;
    long Offset;
};

typedef wxsPositionSizeProperty wxsPositionProperty;
typedef wxsPositionSizeProperty wxsSizeProperty;




#define WXS_POSITION(ClassName,VarName,PGDefName,PGXName,PGYName,PGDUName,DataName) \
  { static wxsPositionProperty _Property(PGDefName,PGXName,PGYName,PGDUName,DataName,wxsOFFSET(ClassName,VarName)); \
    Property(_Property); }


#define WXS_POSITION_P(ClassName,VarName,PGDefName,PGXName,PGYName,PGDUName,DataName,Priority) \
  { static wxsPositionProperty _Property(PGDefName,PGXName,PGYName,PGDUName,DataName,wxsOFFSET(ClassName,VarName),Priority); \
    Property(_Property); }


#define WXS_SIZE(ClassName,VarName,PGDefName,PGWidthName,PGHeightName,PGDUName,DataName) \
  { static wxsSizeProperty _Property(PGDefName,PGWidthName,PGHeightName,PGDUName,DataName,wxsOFFSET(ClassName,VarName)); \
    Property(_Property); }



#define WXS_SIZE_P(ClassName,VarName,PGDefName,PGWidthName,PGHeightName,PGDUName,DataName,Priority) \
  { static wxsSizeProperty _Property(PGDefName,PGWidthName,PGHeightName,PGDUName,DataName,wxsOFFSET(ClassName,VarName),Priority); \
    Property(_Property); }


#endif
